package org.wu.framework.inner.lazy.orm.solon.config;


import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Condition;
import org.noear.solon.annotation.Configuration;
import org.wu.framework.inner.lazy.orm.solon.prop.ExportDataSolonProperties;
import org.wu.framework.lazy.database.datasource.proxy.LazyProxyDataSource;
import org.wu.framework.lazy.database.datasource.proxy.handler.JdbcHandlerAdapter;
import org.wu.framework.lazy.database.datasource.proxy.util.LazyDataSourceProxyUtils;
import org.wu.framework.lazy.orm.database.lambda.LazyBaseDDLOperation;
import org.wu.framework.lazy.orm.database.lambda.LazyBaseDQLOperation;
import org.wu.framework.lazy.orm.database.lambda.dynamic.LazyDynamicDatasourceAdapter;
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;
import org.wu.framework.lazy.orm.core.config.LazyOperationAttribute;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.LazySqlOperation;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.cure.CureAdapter;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.method.LazyOperationMethod;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.method.ddl.LazyDDLOperationMethod;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.method.dql.LazyDQLOperationMethod;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.proxy.LazyDDLOperationProxy;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.proxy.LazyDQLOperationProxy;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.proxy.LazyOperationProxy;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.translation.adapter.LazyTranslationAdapter;
import org.wu.framework.lazy.orm.database.sql.smart.database.SmartLazyOperationAutoStuffed;
import org.wu.framework.lazy.orm.database.sql.smart.database.persistence.LazyOperationSmartAutoStuffed;
import org.wu.framework.lazy.orm.database.sql.smart.database.persistence.PerfectLazyOperation;

import javax.sql.DataSource;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Configuration
public class LazyOperationProxyBeanSolonAutoConfiguration {

    /**
     * 动态数据适配Lazy 适配器
     *
     * @param dataSourceMap 注入的数据源
     * @return LazyDynamicDatasourceAdapter
     */

    @Condition(onMissingBean = LazyDynamicDatasourceAdapter.class)
    @Bean
    public LazyDynamicDatasourceAdapter lazyDynamicAdapter(Map<String, DataSource> dataSourceMap,
                                                           JdbcHandlerAdapter jdbcHandlerAdapter) {
        Map<String, LazyProxyDataSource> lazyProxyDataSourceMap = new ConcurrentHashMap<>();
        dataSourceMap
                .forEach((key, dataSource) ->
                        lazyProxyDataSourceMap.put(key, LazyDataSourceProxyUtils.proxy(dataSource, jdbcHandlerAdapter)));
        LazyDynamicDatasourceAdapter lazyDynamicAdapter =
                new LazyDynamicDatasourceAdapter(lazyProxyDataSourceMap, jdbcHandlerAdapter);
        lazyDynamicAdapter.afterPropertiesSet();
        return lazyDynamicAdapter;
    }


    /**
     * @param lazyOperationMethods   自定义数据库持久层操作方法集合
     * @param cureAdapter            治愈适配器
     * @param lazyDynamicAdapter     动态数据源适配器
     * @param lazyTranslationAdapter 转译适配器
     * @return describe 延迟操作代理Proxy
     * @author Jia wei Wu
     * @date 2021/4/17 7:34 下午
     **/
    @Condition(onMissingBean = LazyOperationProxy.class)
    @Bean
    public LazyOperationProxy lazyOperationProxy(List<LazyOperationMethod> lazyOperationMethods,
                                                 LazyDynamicDatasourceAdapter lazyDynamicAdapter,
                                                 CureAdapter cureAdapter,
                                                 LazyTranslationAdapter lazyTranslationAdapter) {
//        Solon.context().getBeansOfType(LazyOperationMethod.class).forEach((bean) -> {
//            System.out.println("beanClz:" + bean.getClass() );
//        });
        return new LazyOperationProxy(lazyOperationMethods, lazyDynamicAdapter, cureAdapter, lazyTranslationAdapter);
    }

    /**
     * @param lazyOperationProxy 自定义接口实现方法执行代理类 包含执行 DDL、DQL、DML
     * @return describe 延迟操作代理
     * @author Jia wei Wu
     * @date 2021/4/17 7:34 下午
     **/
    @Condition(onMissingBean = LazySqlOperation.class)
    @Bean
    public LazySqlOperation lazySqlOperation(LazyOperationProxy lazyOperationProxy) {
        return (LazySqlOperation) Proxy.newProxyInstance(LazySqlOperation.class.getClassLoader(), new Class[]{LazySqlOperation.class}, lazyOperationProxy);
    }


    /**
     * 升级版 mysql LazyLambdaStream
     *
     * @param lazySqlOperation 懒人操作 下游代理实现的抽象接口
     * @return LazyLambdaStream
     */
    @Bean
    @Condition(onMissingBean = LazyLambdaStream.class)
    public LazyLambdaStream lazyLambdaStream(LazySqlOperation lazySqlOperation) {
        return new LazyLambdaStream(lazySqlOperation);
    }


    @Bean
    @Condition(onMissingBean = SmartLazyOperationAutoStuffed.class)
    public SmartLazyOperationAutoStuffed smartLazyOperationAutoStuffed(LazyOperationAttribute operationConfig, LazyLambdaStream lazyLambdaStream) {
        return new LazyOperationSmartAutoStuffed(operationConfig, lazyLambdaStream);
    }

    /**
     * describe 延迟操作代理DDL Proxy
     *
     * @param lazyDDLOperationMethodList ddl 操作
     * @param lazyDynamicAdapter         动态数据源适配器
     * @return LazyDDLOperationProxy
     * @author Jia wei Wu
     * @date 2021/4/17 7:34 下午
     **/
    @Condition(onMissingBean = LazyDDLOperationProxy.class)
    @Bean
    public LazyDDLOperationProxy lazyDDLOperationProxy(List<LazyDDLOperationMethod> lazyDDLOperationMethodList,
                                                       LazyDynamicDatasourceAdapter lazyDynamicAdapter
    ) {
        return new LazyDDLOperationProxy(lazyDDLOperationMethodList, lazyDynamicAdapter);
    }

    /**
     * describe 延迟操作DDL代理
     *
     * @param lazyDDLOperationProxy ddl 操作代理对象
     * @return LazyBaseDDLOperation
     * @author Jia wei Wu
     * @date 2021/4/17 7:34 下午
     **/
    @Bean
    public LazyBaseDDLOperation lazyBaseDDLOperation(LazyDDLOperationProxy lazyDDLOperationProxy) {
        return (LazyBaseDDLOperation) Proxy.newProxyInstance(LazyBaseDDLOperation.class.getClassLoader(), new Class[]{LazyBaseDDLOperation.class}, lazyDDLOperationProxy);
    }


    /**
     * @param lazyDQLOperationMethods dql 操作
     * @param lazyTranslationAdapter  转译适配器
     * @param lazyDynamicAdapter      动态数据源处理
     * @return describe 延迟操作代理DQLProxy
     * @author Jia wei Wu
     * @date 2021/4/17 7:34 下午
     **/
    @Condition(onMissingBean = LazyDQLOperationProxy.class)
    @Bean
    public LazyDQLOperationProxy lazyDQLOperationProxy(List<LazyDQLOperationMethod> lazyDQLOperationMethods,
                                                       LazyDynamicDatasourceAdapter lazyDynamicAdapter,
                                                       LazyTranslationAdapter lazyTranslationAdapter
    ) {
        return new LazyDQLOperationProxy(lazyDQLOperationMethods, lazyDynamicAdapter, lazyTranslationAdapter);
    }

    /**
     * describe 延迟操作DDL代理
     *
     * @param lazyDQLOperationProxy ddl操作代理对象
     * @return LazyBaseDQLOperation
     * @author Jia wei Wu
     * @date 2021/4/17 7:34 下午
     **/
    @Bean
    public LazyBaseDQLOperation lazyBaseDQLOperation(LazyDQLOperationProxy lazyDQLOperationProxy) {
        return (LazyBaseDQLOperation) Proxy.newProxyInstance(LazyBaseDQLOperation.class.getClassLoader(), new Class[]{LazyBaseDQLOperation.class}, lazyDQLOperationProxy);
    }


    /**
     * 完美处理方式
     *
     * @param exportDataSolonProperties 导出数据配置
     * @param lazyLambdaStream          数据库操作lambda 表达式写法 LazyLambdaStream
     * @return PerfectLazyOperation
     */
    @Condition(onMissingBean = PerfectLazyOperation.class)
    @Bean
    public PerfectLazyOperation perfectLazyOperation(ExportDataSolonProperties exportDataSolonProperties, LazyLambdaStream lazyLambdaStream) {
        return new PerfectLazyOperation(exportDataSolonProperties, lazyLambdaStream);
    }


//    /**
//     * LazyScan 扫描处理器
//     *
//     * @param operation               操作
//     * @param operationConfig         操作配置信息
//     * @param lazyDataSourceAttribute 数据库配置喜讯你
//     * @return LazyBeanPostProcessor
//     */
//    @Condition(onMissingBean = LazyBeanPostProcessor.class)
//    @Bean
//    public LazyBeanPostProcessor lazyBeanPostProcessor(LazyOperation operation,
//                                                       LazyOperationAttribute operationConfig,
//                                                       LazyDataSourceAttribute lazyDataSourceAttribute) {
//        return new LazyBeanPostProcessor(operation, operationConfig, lazyDataSourceAttribute);
//    }



}

